﻿using System.Collections.Generic;
using System.Web;

namespace UniSender
{
    using Expando = Dictionary<string, object>;
    using IExpando = IDictionary<string, object>;

    public interface IEmailAttachment
    {
        string Name { get; }
        
        string GetEncodedContent();
    }

    public abstract class EmailAttachment<T>
    {
        public virtual string Name { get; set; }
        public virtual T Content { get; set; }

        public EmailAttachment(string name, T content)
        {
            Name = name;
            Content = content;
        }

        public abstract string GetEncodedContent();
    }

    public class EmailTextAttachment : EmailAttachment<string>
    {
        public EmailTextAttachment(string name, string content) : base(name, content) { }

        public override string GetEncodedContent()
        {
            return HttpUtility.UrlEncode(Content);
        }
    }

    public class EmailBinaryAttachment : EmailAttachment<byte[]>
    {
        public EmailBinaryAttachment(string name, byte[] content) : base(name, content) { }

        public override string GetEncodedContent()
        {
            return HttpUtility.UrlEncode(Content);
        }
    }

    public abstract class Message
    {
        public virtual string Sender { get; set; }

        public virtual string Body { get; set; }

        public virtual long ListId { get; set; }

        public virtual string Tag { get; set; }

        public virtual int? SeriesDay { get; set; }

        public virtual string SeriesTime { get; set; }

        public virtual string[] Categories { get; set; }

        protected virtual void Serialize(IExpando args)
        {
            args["body"] = Body;
            args["list_id"] = ListId;
            args["tag"] = Tag;
            if (SeriesDay != null)
            {
                args["series_day"] = SeriesDay;
                args["series_time"] = SeriesTime;
            }
            if (Categories != null && Categories.Length > 0)
                args["categories"] = string.Join(",", Categories);
        }

        public virtual IExpando Serialize()
        {
            var args = new Expando();
            Serialize(args);
            return args;
        }
    }

    public class EmailMessage : Message
    {
        public virtual string SenderEmail { get; set; }
        public virtual string Subject { get; set; }
        public virtual string TextBody { get; set; }
        public virtual bool? GenerateText { get; set; }
        public virtual IEmailAttachment[] Attachments { get; set; }
        public virtual string Lang { get; set; }
        public virtual WrapType? WrapType { get; set; }

        public EmailMessage(string senderName, string senderEmail, string subject, string body, long listId)
        {
            Sender = senderName;
            SenderEmail = senderEmail;
            Subject = subject;
            Body = body;
            ListId = listId;
        }

        protected override void Serialize(IExpando args)
        {
            base.Serialize(args);
            args["sender_name"] = Sender;
            args["sender_email"] = SenderEmail;
            args["subject"] = Subject;
            args["text_body"] = TextBody;
            if (TextBody == null && GenerateText == null)
                args["generate_text"] = 1;
            else
                args["generate_text"] = GenerateText;
            args["attachments"] = Attachments;
            args["lang"] = Lang;
            if (WrapType != null)
                args["wrap_type"] = WrapType.Value.Stringify();
        }
    }

    public class SmsMessage : Message
    {
        public SmsMessage(string sender, string body, long listId)
        {
            Sender = sender;
            Body = body;
            ListId = listId;
        }

        protected override void Serialize(IExpando args)
        {
            base.Serialize(args);
            args["sender"] = Sender;
        }
    }
}
